################################################################################
#
#Copyright (c) 2012, Petr Skramovsky
#All rights reserved.
#
#Redistribution and use in source and binary forms, with or without
#modification, are permitted provided that the following conditions are met:
#    * Redistributions of source code must retain the above copyright
#      notice, this list of conditions and the following disclaimer.
#    * Redistributions in binary form must reproduce the above copyright
#      notice, this list of conditions and the following disclaimer in the
#      documentation and/or other materials provided with the distribution.
#
#THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
#ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
#WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
#DISCLAIMED. IN NO EVENT SHALL Petr Skramovsky BE LIABLE FOR ANY
#DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
#(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
#LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
#ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
#(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
#SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
################################################################################

import c4d
import time
import threading
from c4d import gui
from qsystem import QFileSystem
from bspimport import make_c4d_map

PLUGIN_ID = 1028413
MSG_ID_BSP_START = PLUGIN_ID + 1
MSG_ID_BSP_END = PLUGIN_ID + 2
MSG_ID_BSP_ERROR = PLUGIN_ID + 3

def collectPaths(fs,ext):
    r = []
    for k in fs.files.keys():
        if k.endswith(ext):
            r.append(k)
    r.sort()
    return r

def showFSDlg(fs,ext):
    paths = collectPaths(fs,ext)
    os = []
    for p in paths:
        o = c4d.BaseObject(c4d.Opolygon)
        o.SetName(p)
        os.append(o)
    r = gui.SelectionListDialog(os,doc,0,0)
    if r == c4d.NOTOK:
        return None
    return paths[r]

class ImportBSPThread(threading.Thread):
    def __init__(self, path):
        threading.Thread.__init__(self)
        self.path = path
        
    def run (self):
        c4d.SpecialEventAdd(MSG_ID_BSP_START)
        try:
            self.map = make_c4d_map(doc, fs, self.path, 5)
        except Exception, e:
            print e
            c4d.SpecialEventAdd(MSG_ID_BSP_ERROR)
        c4d.SpecialEventAdd(MSG_ID_BSP_END)
                    
fs = QFileSystem("C:\\Program Files (x86)\\Quake III Arena")

class ImportBSPDlg(gui.GeDialog):
    def __init__(self):
        self.ID_TXT_SCALE = 1001
        self.ID_TXT_PATCH = 1002
        self.ID_EDIT_PATH = 2001
        self.ID_BTN_OPEN = 3001
        self.ID_BTN_IMPORT = 3002
        self.ID_SLD_SCALE = 5001
        self.ID_SLD_PATCH = 5002
    
    def SetDefaultValues(self):
        self.SetReal(self.ID_SLD_SCALE, value=1.0, min=0.1, max=10, step=0.1)
        self.SetReal(self.ID_SLD_PATCH, value=5, min=5, max=64, step=1)
        
    def InitValues(self):
        self.SetDefaultValues()
        return True  
    
    def CreateLayout(self):
        self.SetTitle("C4D Quake tools - BSP import")
        self.GroupBegin(4002, c4d.BFH_SCALEFIT, cols=2, rows=1)
        self.AddEditText(self.ID_EDIT_PATH, c4d.BFH_SCALEFIT)
        self.AddButton(self.ID_BTN_OPEN, c4d.BFH_RIGHT, name="...")
        self.GroupEnd()
        self.GroupBegin(4001, c4d.BFH_SCALEFIT, cols=2, rows=2)
        self.AddStaticText(self.ID_TXT_PATCH, c4d.BFH_LEFT, name="Patch segmentation : ")
        self.AddEditSlider(self.ID_SLD_PATCH, c4d.BFH_SCALEFIT)
        self.AddStaticText(self.ID_TXT_SCALE, c4d.BFH_LEFT, name="Scale : ")
        self.AddEditSlider(self.ID_SLD_SCALE, c4d.BFH_SCALEFIT)
        self.GroupEnd()
        self.import_button = self.AddButton(self.ID_BTN_IMPORT, c4d.BFV_CENTER, name="IMPORT")
        return True
    
    
    def CoreMessage(self, id, msg):
        if id == MSG_ID_BSP_START:
            c4d.StatusSetText("Importing .bsp...")
            c4d.StatusSetSpin()
            self.Enable(self.import_button, False)
            return True
        elif id == MSG_ID_BSP_END:
            map = self.thread.map
            for p in map.GetChildren():
                doc.SetActiveObject(p,c4d.SELECTION_ADD)
            doc.InsertObject(map)
            c4d.CallCommand(12139)
            c4d.CallCommand(13323)
            c4d.CallCommand(14039)
            doc.SetChanged()
            
            c4d.StatusClear()
            self.Enable(self.import_button, True)
            return True
        elif id == MSG_ID_BSP_ERROR:
            gui.MessageDialog( "Some error occured, check python console for more details." )
            c4d.StatusClear()
            self.Enable(self.import_button, True)
            return True
        return gui.GeDialog.CoreMessage(self, id, msg)
    
    def Command(self, id, msg):
        if id == self.ID_BTN_OPEN:
            path = showFSDlg(fs,".bsp")
            if path:
                self.SetFilename(self.ID_EDIT_PATH, path)
        elif id == self.ID_BTN_IMPORT:
            path = self.GetFilename(self.ID_EDIT_PATH)
            if path is None or path == "":
                gui.MessageDialog("Select .bsp first.")
                return True
            self.thread = ImportBSPThread(path)
            self.thread.start()
        return True
      
    def Show(self):
        self.Open(dlgtype=c4d.DLG_TYPE_MODAL, defaultw=400, defaulth=280, pluginid=PLUGIN_ID)

dlg = ImportBSPDlg()
dlg.Show()